﻿using System;
using System.Linq.Expressions;
using PropertyExpression.Common;
using PropertyExpression.ControllableQuery.TypedReader;

namespace PropertyExpression.ControllableQuery.Test
{
    public static class DataReaderExtensions
    {
        public static Guid GetValue<T>(this IDataReader<T> it, Expression<Func<T, Guid>> propertyExpression)
        {
            return it.GetValue(propertyExpression, value => (Guid)value);
        }

        public static Decimal<TPrecision, TScale> GetValue<T, TPrecision, TScale>(
            this IDataReader<T> it, Expression<Func<T, Decimal<TPrecision, TScale>>> propertyExpression)
            where TPrecision : IPrecision where TScale : IScale
        {
            return it.GetValue(propertyExpression, value => new Decimal<TPrecision, TScale>((decimal) value));
        }

        public static Money GetValue<T>(this IDataReader<T> it, Expression<Func<T, Money>> propertyExpression)
        {
            return it.GetValue(propertyExpression, value => new Money((decimal)value));
        }

        public static NVarChar<TLength> GetValue<T, TLength>(this IDataReader<T> it, Expression<Func<T, NVarChar<TLength>>> propertyExpression)
            where TLength : ILength
        {
            return it.GetValue(propertyExpression, value => new NVarChar<TLength>((string)value));
        }

        public static IOptionalValue<TProperty> GetValue<T, TProperty>(this IDataReader<T> it, Expression<Func<T, IOptionalValue<TProperty>>> propertyExpression)
        {
            return it.GetValue(propertyExpression, value => value == DBNull.Value ? OptionalValue.Nothing<TProperty>() : ((TProperty)value).AsOptionalValue());
        }

        public static IOptionalValue<NVarChar<TProperty>> GetValue<T, TProperty>(this IDataReader<T> it, Expression<Func<T, IOptionalValue<NVarChar<TProperty>>>> propertyExpression)
            where TProperty : ILength
        {
            return it.GetValue(propertyExpression, value => value == DBNull.Value ? OptionalValue.Nothing<NVarChar<TProperty>>() : new NVarChar<TProperty>((string)value).AsOptionalValue());
        }        
    }
}